from sc.model.models import Player, Map, Team, League, LeagueStage
from sc.model.models import CommentarySet, Match, ProleagueMatch, Game
from sc.model.meta import Session

class Updater(object):
    RACE_CONVERSION = {
        'terran' : 't',
        'protoss' : 'p',
        'zerg' : 'z',
        'other' : '?'
    }

    def _get_or_create(self, type, id, builder):
        entity = Session.query(type).get(id)

        if entity is None:
            entity = builder()
            Session.add(entity)
        return entity

    def player(self, player_id, name, race):
        p = self._get_or_create(Player, player_id, lambda: Player(player_id))

        p.name = name
        p.race = self.RACE_CONVERSION[race]

        Session.commit()

    def map(self, map_id, name, version, width, height):
        m = self._get_or_create(Map, map_id, lambda: Map(map_id))

        m.name = name
        m.version = version
        m.width = width
        m.height = height

        Session.commit()

    def team(self, team_id, name):
        t = self._get_or_create(Team, team_id, lambda: Team(team_id))

        t.name = name
        t.name_key = name.replace(' ', '')
        Session.commit()

    def league(self, name_key, name):
        builder = lambda: League(name_key)
        league = self._get_or_create(League, name_key, builder)
        league.name = name
        Session.commit()

    def _get_league_stage(self, league, stage_path):
        parent_stage = Session.query(League).get(league)
        for name_key in stage_path:
            parent_stage = parent_stage.stages[name_key]

        return parent_stage

    def league_stage(self, league, stage_path, name, start_date, end_date,
            format):

        parent_stage = self._get_league_stage(league, stage_path[:-1])

        name_key = stage_path[-1]
        if name_key in parent_stage.stages:
            league_stage = parent_stage.stages[name_key]
        else:
            league_stage = LeagueStage(name_key)
            parent_stage.stages[name_key] = league_stage

        league_stage.name = name
        league_stage.start_date = start_date
        league_stage.end_date = end_date
        league_stage.format = format

        Session.commit()

    def proleague_match_id(self, league, stage_path,
            match_id, team_one, team_two):

        league_stage = self._get_league_stage(league, stage_path)
        if match_id in league_stage.matches:
            match = league_stage.matches[match_id]
        else:
            match = ProleagueMatch(match_id)
            match.team_one_id = team_one
            match.team_two_id = team_two
            league_stage.matches[match_id] = match

        Session.commit()

    def proleague_match_data(self, match_id, winner, winner_score, loser_score):
        match = Session.query(ProleagueMatch).get(match_id)
        match.winner_id = winner
        match.winner_score = winner_score
        match.loser_score = loser_score

        Session.commit()

    def game(self, match_id, game_number, date_played, game_map,
            player_one, player_one_start_location,
            player_two, player_two_start_location,
            winner, playtime):

        match = Session.query(Match).get(match_id)
        if not game_number in match.games:
            game = Game(match_id, game_number)
            match.games[game_number] = game
        else:
            game = match.games[game_number]

        game.date_played = date_played
        game.game_map_id = game_map
        game.player_one_id = player_one
        game.player_one_start_location = player_one_start_location
        game.player_two_id = player_two
        game.player_two_start_location = player_two_start_location
        game.winner_id = winner
        game.playtime = playtime

        Session.commit()

    def commentary_set(self, match_id, game_number, author, video_ids):

        match = Session.query(Match).get(match_id)
        game = match.games[game_number]

        if author in game.commentary_sets:
            commentary_set = game.commentary_sets[author]
        else:
            commentary_set = CommentarySet(author)
            game.commentary_sets[author] = commentary_set

        commentary_set.video_ids = video_ids

        Session.commit()



